/*!
 * \file WtBtRunner.cpp
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief WonderTrader回测运行器主程序实现
 * 
 * \details 本文件实现了WonderTrader回测系统的主程序入口，负责：
 *          - 回测系统的初始化和配置加载
 *          - 历史数据回放器的创建和配置
 *          - 不同类型策略模拟器的创建和初始化
 *          - 支持CTA、HFT、SEL、EXEC、UFT五种回测模式
 *          - 回测执行流程的控制和管理
 *          - 日志系统和异常处理的集成
 *          - 跨平台支持和内存转储功能
 *          
 *          该程序是WonderTrader回测系统的独立可执行文件，
 *          通过配置文件驱动不同类型的策略回测。
 */
#include "../WtBtCore/HisDataReplayer.h"
#include "../WtBtCore/CtaMocker.h"
#include "../WtBtCore/ExecMocker.h"
#include "../WtBtCore/HftMocker.h"
#include "../WtBtCore/SelMocker.h"
#include "../WtBtCore/UftMocker.h"
#include "../WtBtCore/WtHelper.h"

#include "../WTSTools/WTSLogger.h"
#include "../WTSUtils/SignalHook.hpp"

#include "../WTSUtils/WTSCfgLoader.h"
#include "../Includes/WTSVariant.hpp"
#include "../Share/StdUtils.hpp"

#ifdef _MSC_VER
#include "../Common/mdump.h"
#endif

/*!
 * \brief 回测运行器主程序入口
 * 
 * \details 回测运行器的主函数，负责整个回测系统的启动和运行：
 *          
 *          1. 系统初始化：
 *             - 启用内存转储功能（Windows平台）
 *             - 初始化日志系统
 *             - 安装信号处理器（Unix平台）
 *          
 *          2. 配置加载：
 *             - 加载回测配置文件（configbt.json/yaml）
 *             - 解析回测环境参数
 *             - 获取回测模式和滑点设置
 *          
 *          3. 回测器创建：
 *             - 创建历史数据回放器
 *             - 根据模式创建对应的策略模拟器：
 *               * CTA模式：趋势跟踪策略回测
 *               * HFT模式：高频交易策略回测
 *               * SEL模式：选股策略回测
 *               * EXEC模式：执行器回测
 *               * UFT模式：超高频交易策略回测
 *          
 *          4. 回测执行：
 *             - 准备回测数据和环境
 *             - 启动历史数据回放
 *             - 等待用户输入退出
 * 
 * \return int 程序退出码，0表示正常退出，-1表示配置加载失败
 * 
 * \note 支持的配置文件格式：JSON和YAML
 * \warning 确保配置文件存在且格式正确
 */
int main()
{
#ifdef _MSC_VER
    // Windows平台启用内存转储功能，用于调试崩溃问题
    CMiniDumper::Enable("WtBtRunner.exe", true, WtHelper::getCWD().c_str());
#endif

	// 初始化日志系统，优先使用JSON格式配置文件
	std::string filename = "logcfgbt.json";
	if (!StdFile::exists(filename.c_str()))
		filename = "logcfgbt.yaml";

	WTSLogger::init(filename.c_str());

#if _WIN32
// Signal hooks disabled in WIN32
#else
// Signal hooks enabled in UNIX
	// Unix平台安装信号处理器，用于优雅处理系统信号
	install_signal_hooks([](const char* message) {
		WTSLogger::error(message);
	});
#endif

	// 加载回测配置文件，优先使用JSON格式
	filename = "configbt.json";
	if(!StdFile::exists(filename.c_str()))
		filename = "configbt.yaml";

	WTSVariant* cfg = WTSCfgLoader::load_from_file(filename.c_str(), true);
	if (cfg == NULL)
	{
		WTSLogger::info_f("Loading configuration file {} failed", filename);
		return -1;
	}

	// 创建并初始化历史数据回放器
	HisDataReplayer replayer;
	replayer.init(cfg->get("replayer"));

	// 解析回测环境配置
	WTSVariant* cfgEnv = cfg->get("env");
	const char* mode = cfgEnv->getCString("mocker");  // 回测模式
	int32_t slippage = cfgEnv->getInt32("slippage");  // 滑点设置

	// 根据回测模式创建对应的策略模拟器
	if (strcmp(mode, "cta") == 0)
	{
		// CTA策略回测模式：适用于趋势跟踪、技术指标等中低频策略
		CtaMocker* mocker = new CtaMocker(&replayer, "cta", slippage);
		mocker->init_cta_factory(cfg->get("cta"));
		replayer.register_sink(mocker, "cta");
	}
	else if (strcmp(mode, "hft") == 0)
	{
		// HFT高频交易回测模式：适用于高频交易策略
		HftMocker* mocker = new HftMocker(&replayer, "hft");
		mocker->init_hft_factory(cfg->get("hft"));
		replayer.register_sink(mocker, "hft");
	}
	else if (strcmp(mode, "sel") == 0)
	{
		// SEL选股策略回测模式：适用于股票选股策略
		SelMocker* mocker = new SelMocker(&replayer, "sel", slippage);
		mocker->init_sel_factory(cfg->get("cta"));
		replayer.register_sink(mocker, "sel");
	}
	else if (strcmp(mode, "exec") == 0)
	{
		// EXEC执行器回测模式：适用于执行算法回测
		ExecMocker* mocker = new ExecMocker(&replayer);
		mocker->init(cfg->get("exec"));
		replayer.register_sink(mocker, "exec");
	}
	else if (strcmp(mode, "uft") == 0)
	{
		// UFT超高频交易回测模式：适用于微秒级超高频策略
		UftMocker* mocker = new UftMocker(&replayer, "uft");
		mocker->init_uft_factory(cfg->get("uft"));
		replayer.register_sink(mocker, "uft");
	}

	// 准备回测环境和数据
	replayer.prepare();

	// 开始执行回测
	replayer.run();

	// 等待用户输入，保持程序运行直到手动退出
	printf("press enter key to exit\r\n");
	getchar();

	// 停止日志系统
	WTSLogger::stop();
}
